﻿using System;
using System.Linq.Expressions;

namespace CompactMapper.Orm.Queries
{
    public abstract class Criterion
    {
        #region CriterionType enum

        public enum CriterionType
        {
            StringEquals,
            StringLike,
            EnumEquals,
            PrimaryKeyEquals,
            IntegerEquals,
            LongEquals
        }

        #endregion

        public abstract CriterionType Type { get; }
    }

    public abstract class Criterion<T> : Criterion
    {
        public abstract String PropertyName { get; }
        public abstract object PropertyValue { get; }
        public abstract Boolean Validate(T entity);
    }

    public abstract class Criterion<T, TColumn> : Criterion<T>
    {
        private readonly string _propertyName;

        protected Criterion(Expression<Func<T, TColumn>> columnExpression, TColumn targetValue)
        {
            _propertyName = ((MemberExpression) columnExpression.Body).Member.Name;
            TargetValue = targetValue;
        }

        protected Criterion(String columnName, TColumn targetValue)
        {
            _propertyName = columnName;
            TargetValue = targetValue;
        }

        public TColumn TargetValue { get; private set; }

        public override sealed string PropertyName
        {
            get { return _propertyName; }
        }

        public override sealed object PropertyValue
        {
            get { return TargetValue; }
        }
    }
}